package eu.irreality.dai.gameplay.controller.actions.interaction;

import eu.irreality.dai.gameplay.actions.Action;
import eu.irreality.dai.gameplay.actions.interaction.OpenAction;
import eu.irreality.dai.gameplay.controller.actions.ControllerAction;
import eu.irreality.dai.gameplay.entities.AliveEntity;
import eu.irreality.dai.gameplay.events.GameEvent;
import eu.irreality.dai.gameplay.states.WhichDirectionState;
import eu.irreality.dai.gameplay.world.GameWorld;
import eu.irreality.dai.ui.cell.DisplayableObject;
import eu.irreality.dai.ui.keyboard.KeyProcessor;
import eu.irreality.dai.util.Direction;
import eu.irreality.dai.util.Position;
import eu.irreality.dai.util.SortedList;
import eu.irreality.dai.util.exceptions.GameException;
import eu.irreality.dai.util.exceptions.InternalErrorException;
import eu.irreality.dai.world.gen.LevelGenerator;
import eu.irreality.dai.world.level.Level;

public class TryOpenAction extends ControllerAction
{

    public TryOpenAction(KeyProcessor kp, GameWorld world, AliveEntity entity)
    {
	super(kp, world, entity);
    }

    @Override
    public void execute() throws GameException, InternalErrorException
    {
	Level level = world.getActiveLevel(); // TODO: Entity.getLevel()?

	Position pos = entity.getPosition();
	int col = pos.getCol();
	int row = pos.getRow();

	int numClosedDoors = 0;
	int rowClosedDoor = -1;
	int colClosedDoor = -1;
	boolean endLoop = false;

	for (int c = -1; c <= 1; c++)
	{
	    for (int r = -1; r <= 1; r++)
	    {
		int newCol = col + c;
		int newRow = row + r;
		SortedList tempList = level.get(newRow, newCol);
		if (tempList != null && !tempList.isEmpty())
		{
		    for (Object o : tempList)
		    {
			DisplayableObject dispO = (DisplayableObject) o;
			if (dispO.equals(LevelGenerator.CLOSED_DOOR))
			{
			    numClosedDoors++;
			    colClosedDoor = newCol;
			    rowClosedDoor = newRow;
			    if (numClosedDoors > 1)
			    {
				endLoop = true;
				break;
			    }
			}
		    }
		    if (endLoop)
		    {
			break;
		    }
		}
	    }
	    if (endLoop)
	    {
		break;
	    }
	}

	if (numClosedDoors == 0)
	{
	    world.notifyObservers(new GameEvent(level, new Position(row, col),
		    entity, null, GameEvent.WHAT_DOOR));
	}

	if (numClosedDoors == 1)
	{
	    new OpenAction(world, entity, new Position(rowClosedDoor,
		    colClosedDoor)).execute();
	}

	if (numClosedDoors > 1)
	{
	    world
		    .notifyObservers(new String[] { "message",
			    " Which direction?" });
	    kp.setState(new WhichDirectionState(
		    new WhichDirectionState.DirectionToAction()
		    {

			public Action getAction(Direction d)
			{
			    OpenAction oa = new OpenAction(world, entity);
			    oa.setDirection(d);
			    return oa;
			}

		    }));
	}
    }
}